package com.kgis.map.handler.feature.draw {
    import com.kgis.map.Map;
    import com.kgis.map.common.enum.HandlerEnum;
    import com.kgis.map.common.enum.MapActionEnum;
    import com.kgis.map.events.DrawEvent;
    import com.kgis.map.events.MapEvent;
    import com.kgis.map.feature.Feature;
    import com.kgis.map.geometry.PointGeometry;
    import com.kgis.map.geometry.PolygonGeometry;
    import com.kgis.map.geometry.PolylineGeometry;
    import com.kgis.map.geometry.basetype.Location;
    import com.kgis.map.geometry.basetype.Pixel;
    import com.kgis.map.handler.mouse.ClickHandler;
    import com.kgis.map.style.IStyle;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    import flash.ui.Keyboard;
    import com.kgis.map.handler.feature.draw.AbstractDrawHandler;

    /**
     * This handler manage the function draw of the polygon.
     * Active this handler to draw a polygon.
     */
    [ExcludeClass]
    public class DrawPolygonHandler extends AbstractDrawHandler {

        private var feature:Feature = null;
        private var _firstPointFeature:Feature = null;
        private var _firstPointGepmetry:PointGeometry;
        private var _firstPointPixel:Pixel;
        private var _newFeature:Boolean = true;
        private var _clickHandler:ClickHandler = null;

        /**
         * As we draw a first point to know where we started the polygon
         */
        private var _firstPointRemoved:Boolean = false;

        /**
         * Single id of the polygon
         */
        private var id:Number = 0;

        /**
         * position of the last point drawn
         * */
        private var _lastPointPixel:Pixel = null;
        private var _lastPoint:PointGeometry = null;
        private var pointDown:PointGeometry;
        private var pointUp:PointGeometry;
        private var polygon:PolygonGeometry = null;

        private var count:int = 0;

        /**
         * Constructor of the polygon handler
         * @param map the map reference
         */
        public function DrawPolygonHandler(map:Map, handlername:String) {
            this._clickHandler = new ClickHandler(map, HandlerEnum.CLICK_HANDLER);
            super(map, handlername);
        }

        override protected function registerListeners():void {
            map.operateMode = MapActionEnum.MAP_DRAW;
            this._clickHandler.active = true;
            this._clickHandler.doubleClick = this.mouseDblClick;

            if (this.map) {
                this.map.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
                this.map.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
                this.map.addEventListener(MapEvent.MOVE_END, this.updateZoom);
                this.map.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
                this.map.addEventListener(DrawEvent.DRAW_START_POINT, drawStartPoint);
                this.map.addEventListener(DrawEvent.DRAW_END_POINT, drawEndPoint);
                this.map.stage.addEventListener(KeyboardEvent.KEY_DOWN, backToPreviousPoint);
            }

        }

        override protected function unregisterListeners():void {
            this._clickHandler.active = false;

            if (this.map) {
                this.map.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
                this.map.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
                this.map.stage.removeEventListener(KeyboardEvent.KEY_DOWN, backToPreviousPoint);
                this.map.removeEventListener(MapEvent.MOVE_END, this.updateZoom);
                this.map.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
                this.map.removeEventListener(DrawEvent.DRAW_START_POINT, drawStartPoint);
                this.map.removeEventListener(DrawEvent.DRAW_END_POINT, drawEndPoint);
            }
            this.map.operateMode = MapActionEnum.MAP_PAN;
            _snapLayerIds = null;
            _snapLayers = null;
            newFeature = true;
            count = 0;
            drawLayer.graphics.clear();
        }

        private function mouseMoveHandler(event:MouseEvent):void {
            super.mouseMoveSnapHandler(event);

            //画动态线
            if (!newFeature) {
                drawTemporaryPolygon(event);
            }

        }

        /**
         * mouseDownHandler与mouseUpHandler配合，判断当前鼠标按下是漫游还是点击
         * */
        private function mouseDownHandler(event:MouseEvent):void {
            var pixel:Pixel = new Pixel(event.currentTarget.mouseX, event.currentTarget.mouseY);
            var lonlat:Location = this.map.getLocationFromLayerPx(pixel);

            pointDown = new PointGeometry(lonlat.lon, lonlat.lat);
        }

        private function mouseUpHandler(event:MouseEvent):void {
            var pixel:Pixel = new Pixel(event.currentTarget.mouseX, event.currentTarget.mouseY);
            var lonlat:Location = this.map.getLocationFromLayerPx(pixel);

            pointUp = new PointGeometry(lonlat.lon, lonlat.lat);
            if (!pointUp.equals(pointDown)) {
                //漫游状态，不需要绘制点
            }
            else {
                drawPolygon(event);
            }
        }

        protected function drawPolygon(event:MouseEvent = null):void {
            count++;
            if (drawLayer != null) {
                var style:IStyle = drawLayer.geoStyle;

                drawLayer.graphics.clear();
                var pixel:Pixel = new Pixel(drawLayer.mouseX, drawLayer.mouseY);
                this._lastPointPixel = new Pixel(drawLayer.mouseX, drawLayer.mouseY);
                var lonlat:Location = this.map.getLocationFromLayerPx(pixel);
                var point:PointGeometry = new PointGeometry(lonlat.lon, lonlat.lat);

                var lring:PolylineGeometry = null;


                if (snapReturn != null) {
                    point = new PointGeometry(snapReturn.snapPoint.x, snapReturn.snapPoint.y);
                    _lastPointPixel = this.map.getLayerPxFromLocation(new Location(point.x, point.y));
                    if (this.snapClickCallback != null) {
//                        this.snapClickCallback(snapReturn.snapFeature, point);
						this.snapClickCallback(snapReturn.snapFeatures, point);
                    }
                    snapReturn = null;
                }
                if (newFeature) {
                    _firstPointGepmetry = point;
                    lring = new PolylineGeometry();
                    lring.pointList.addItem(point);
                    _lastPoint = point;

                    trace("first  point" + count + ":" + drawLayer.mouseX + "  " + drawLayer.mouseY);
                    polygon = new PolygonGeometry();
                    polygon.lineList.addItem(lring);
                    _firstPointPixel = this.map.getLayerPxFromLocation(new Location(point.x, point.y));


                    newFeature = false;

                    this.map.addEventListener(MapEvent.MOVE_END, updateZoom);
                    //抛出新增点事件
                    this.map.dispatchEvent(new DrawEvent(DrawEvent.DRAW_NEW_POINT, this.feature, lonlat));
                }
                else {
                    if (count == 2) {
                        this.feature = new Feature(polygon, null, style, null);
                        this.feature.name = "polygon." + id.toString();;
                        this.feature.labelVisible = false;
                        this.feature.isLocked = true;
                        ++id;
                        drawLayer.addFeature(feature);
                        this.feature.unregisterListeners();
                    }
                    if (!point.equals(_lastPoint)) {
                        lring = polygon.lineList.getItemAt(0) as PolylineGeometry;
                        lring.addPoint(point);
                        count++;
                        trace("第" + count + "次" + ":" + drawLayer.mouseX + "  " + drawLayer.mouseY);
                        _lastPoint = point;
                        if (this.feature) {
                            this.feature.executeDrawing();
                        }

                        //抛出新增点事件
                        this.map.dispatchEvent(new DrawEvent(DrawEvent.DRAW_NEW_POINT, this.feature, lonlat));

                    }

                }
                    //  drawLayer.redraw();

            }
        }

        //回退到上一个绘制点||结束绘制
        private function backToPreviousPoint(event:KeyboardEvent):void {
            if (event.charCode == Keyboard.ESCAPE) {
                if (null == polygon) {
                    this.map.dispatchEvent(new DrawEvent(DrawEvent.DRAW_POLYGON_FEATURE_END, null));
                    return;
                }
                var line:PolylineGeometry = polygon.lineList.getItemAt(0) as PolylineGeometry;
                if (line.pointList.length < 1) {
                    return;
                }
                line.removePointByIndex();
                if (null != this.feature) {
                    this.feature.executeDrawing();
                }
                if (line.pointList.length == 0) {
                    if (count > 1) {
                        drawLayer.removeFeature(feature);
                    }
                    count = 0;
                    drawLayer.graphics.clear();
                    this.active = false;
                    if (!newFeature) {
                        newFeature = true;
                    }
                    this.map.dispatchEvent(new DrawEvent(DrawEvent.DRAW_POLYGON_FEATURE_END, null));
                    this.map.stage.removeEventListener(KeyboardEvent.KEY_DOWN, backToPreviousPoint);
                }
                else {
                    var point:PointGeometry = line.getLastPoint();
                    _lastPointPixel = this.map.getLayerPxFromLocation(new Location(point.x, point.y));
                    drawTemporaryPolygon();
                }

            }
        }

        public function mouseDblClick(LastPX:Pixel, ... rest):void {
            drawPolygon();
            drawFinalPoly();
			this.active=false;
        }

        private function updateZoom(evt:MapEvent):void {

            if (evt.zoomChanged) {
                drawLayer.graphics.clear();
                if (polygon) {
                    var tempPoint:PointGeometry = _firstPointGepmetry;
                    _firstPointPixel = this.map.getLayerPxFromLocation(new Location(tempPoint.x, tempPoint.y));
                    //尾
                    _lastPointPixel = this.map.getLayerPxFromLocation(new Location(_lastPoint.x, _lastPoint.y));
                    drawTemporaryPolygon();
                }

            }
        }

        public function drawTemporaryPolygon(event:MouseEvent = null):void {
            drawLayer.graphics.clear();
            drawLayer.graphics.beginFill(0x00ff00, 0.5);
            drawLayer.graphics.lineStyle(2, 0x00ff00);
            drawLayer.graphics.moveTo(drawLayer.mouseX, drawLayer.mouseY);
            drawLayer.graphics.lineTo(this._firstPointPixel.x, this._firstPointPixel.y);
            drawLayer.graphics.moveTo(drawLayer.mouseX, drawLayer.mouseY);
            drawLayer.graphics.lineTo(this._lastPointPixel.x, this._lastPointPixel.y);
            drawLayer.graphics.endFill();

            //抛出画面过程中鼠标移动事件
            var pixel:Pixel = new Pixel(drawLayer.mouseX, drawLayer.mouseY);
            var lonlat:Location = this.map.getLocationFromLayerPx(pixel);
            this.map.dispatchEvent(new DrawEvent(DrawEvent.DRAW_POINT_MOUSEMOVING, this.feature, lonlat));
        }

        /**
         * Finish the polygon
         */
        public function drawFinalPoly():void {
            drawLayer.graphics.clear();
            if (this.feature != null) {
                //(polygon.lineList.getItemAt(0) as PolylineGeometry).removePointByIndex();
                (polygon.lineList.getItemAt(0) as PolylineGeometry).addPoint(_firstPointGepmetry.clone());
                trace("最后一次" + ":" + _firstPointPixel.x + "  " + _firstPointPixel.y);
                if ((polygon.lineList.getItemAt(0) as PolylineGeometry).pointList.length > 2) {
                    this.feature.geoStyle = drawLayer.geoStyle;

                    this.feature.registerListeners();

                }
                else {
                    drawLayer.removeFeature(this.feature);
                }
                /**
                 * 标记
                 * */
                this.feature.isLocked = false;
                this.feature.executeDrawing();
            }
            newFeature = true;
            this.map.removeEventListener(MouseEvent.MOUSE_MOVE, drawTemporaryPolygon);
            this.map.removeEventListener(MapEvent.MOVE_END, updateZoom);
            this.map.stage.removeEventListener(KeyboardEvent.KEY_DOWN, backToPreviousPoint);
            this.map.dispatchEvent(new DrawEvent(DrawEvent.DRAW_POLYGON_FEATURE_END, this.feature));
            count = 0;
        }

        override public function set map(value:Map):void {
            super.map = value;
            this._clickHandler.map = value;

        }

        public function set newFeature(value:Boolean):void {
            _newFeature = value;
        }

        /**
         * To know if we create a new feature, or if some points are already added
         */
        public function get newFeature():Boolean {
            return _newFeature;
        }

        /**
         *this attribute is used to see a point the first time
         * the user clicks
         **/
        public function get firstPointRemoved():Boolean {
            return _firstPointRemoved;
        }

        /**
         * Handler which manage the doubleClick, to finalize the polygon
         */
        public function get clickHandler():ClickHandler {
            return _clickHandler;
        }
    }
}

